package com.rankeiot.core.excel;

import ch.rabanti.nanoxlsx4j.Cell;
import ch.rabanti.nanoxlsx4j.styles.Style;


import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.function.Consumer;


/**
 * 流式批量导出Excel数据，如果需要直接从数据库导出，可以使用ExcelStreamExporter
 *
 * @see ExcelStreamExporter
 */
public class ExcelBatchExporter {
    private int max_row = 1048575;
    private OutputStream out;
    private int currentIndex = 0;
    private int currentRow = 0;
    private XlsxStreamWriter writer;
    private XlsxStreamWriter.SheetWriter sw;

    private Style defaultStyle=null;
    private List<Cell> headerRow;
    public ExcelBatchExporter(OutputStream out) {
        defaultStyle=ExcelStreamExporter.createStyle();
        this.out = out;
    }

    public void export(Consumer<BatchWriter> callback) throws Throwable {
        writer = new XlsxStreamWriter(out);

        writer.getStyles().addStyle(defaultStyle);

        createNewSheet();
        callback.accept(new BatchWriter());
        sw.end();
        writer.close();
    }

    public int getMaxRow() {
        return max_row;
    }

    /**
     * 设置单个sheet的最大行数
     *
     * @param count
     */
    public void setMaxRow(int count) {
        this.max_row = count;
    }

    public void setHeaderRow(List<Cell> headerRow) {
        this.headerRow = headerRow;
    }
    public void setHeaderRow(Object ...values) {
        this.headerRow = XlsxStreamWriter.toDefaultRow(null,values);
    }

    private void createNewSheet() throws IOException {
        if(sw!=null){
            sw.end();
        }
        currentIndex++;
        sw=writer.createSheet("sheet"+currentIndex);
        if(headerRow!=null){
            sw.writeRowCells(headerRow);
        }
    }
    public class BatchWriter {
        public void writeRow(Object... values) throws IOException {
            List<Cell> cells = XlsxStreamWriter.toDefaultRow(defaultStyle,values);
            writeRow(cells);
        }

        public void writeRow(List<Cell> cells) throws IOException {
            //切换下一个Sheet
            if (currentRow >= max_row) {
                createNewSheet();
                currentRow=0;
            }
            sw.writeRowCells(cells);
            currentRow++;
        }
    }
}
